package net.lab1024.sa.admin.module.business.pdf.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * OCR性能优化工具类
 *
 * @Author 1024创新实验室
 */
@Slf4j
@Component
public class OcrPerformanceOptimizer {

    // 性能统计
    private final AtomicLong totalProcessingTime = new AtomicLong(0);
    private final AtomicInteger totalPagesProcessed = new AtomicInteger(0);
    private final AtomicInteger successfulOcrCount = new AtomicInteger(0);
    private final AtomicInteger failedOcrCount = new AtomicInteger(0);
    
    // 页面处理时间统计
    private final Map<Integer, Long> pageProcessingTimes = new ConcurrentHashMap<>();
    
    // 内存使用统计
    private final AtomicLong peakMemoryUsage = new AtomicLong(0);
    
    /**
     * 记录页面处理开始
     */
    public void recordPageStart(int pageNumber) {
        pageProcessingTimes.put(pageNumber, System.currentTimeMillis());
    }
    
    /**
     * 记录页面处理完成
     */
    public void recordPageComplete(int pageNumber, boolean success, long memoryUsage) {
        Long startTime = pageProcessingTimes.remove(pageNumber);
        if (startTime != null) {
            long processingTime = System.currentTimeMillis() - startTime;
            totalProcessingTime.addAndGet(processingTime);
            totalPagesProcessed.incrementAndGet();
            
            if (success) {
                successfulOcrCount.incrementAndGet();
            } else {
                failedOcrCount.incrementAndGet();
            }
            
            // 记录峰值内存使用
            long currentPeak = peakMemoryUsage.get();
            while (memoryUsage > currentPeak) {
                if (peakMemoryUsage.compareAndSet(currentPeak, memoryUsage)) {
                    break;
                }
                currentPeak = peakMemoryUsage.get();
            }
            
            log.debug("页面 {} 处理完成，耗时: {}ms，内存使用: {}MB，成功: {}", 
                     pageNumber, processingTime, memoryUsage / 1024 / 1024, success);
        }
    }
    
    /**
     * 获取性能统计信息
     */
    public OcrPerformanceStats getPerformanceStats() {
        int totalPages = totalPagesProcessed.get();
        long totalTime = totalProcessingTime.get();
        
        OcrPerformanceStats stats = new OcrPerformanceStats();
        stats.setTotalPagesProcessed(totalPages);
        stats.setTotalProcessingTimeMs(totalTime);
        stats.setAverageProcessingTimeMs(totalPages > 0 ? totalTime / totalPages : 0);
        stats.setSuccessfulOcrCount(successfulOcrCount.get());
        stats.setFailedOcrCount(failedOcrCount.get());
        stats.setSuccessRate(totalPages > 0 ? (double) successfulOcrCount.get() / totalPages * 100 : 0);
        stats.setPeakMemoryUsageMB(peakMemoryUsage.get() / 1024 / 1024);
        
        return stats;
    }
    
    /**
     * 获取性能优化建议
     */
    public String getOptimizationSuggestions() {
        OcrPerformanceStats stats = getPerformanceStats();
        StringBuilder suggestions = new StringBuilder();
        
        // 基于处理时间的建议
        if (stats.getAverageProcessingTimeMs() > 10000) { // 超过10秒
            suggestions.append("1. 处理时间过长，建议：\n");
            suggestions.append("   - 降低图片DPI（当前建议：150-200）\n");
            suggestions.append("   - 减少图片预处理步骤\n");
            suggestions.append("   - 使用更快的OCR引擎模式\n\n");
        }
        
        // 基于成功率的建议
        if (stats.getSuccessRate() < 70) { // 成功率低于70%
            suggestions.append("2. 识别成功率较低，建议：\n");
            suggestions.append("   - 检查Tesseract语言包是否正确安装\n");
            suggestions.append("   - 调整图像预处理参数\n");
            suggestions.append("   - 尝试不同的页面分割模式\n");
            suggestions.append("   - 确保图片质量足够清晰\n\n");
        }
        
        // 基于内存使用的建议
        if (stats.getPeakMemoryUsageMB() > 1024) { // 超过1GB
            suggestions.append("3. 内存使用过高，建议：\n");
            suggestions.append("   - 减少并发处理线程数\n");
            suggestions.append("   - 降低图片分辨率\n");
            suggestions.append("   - 增加JVM堆内存\n\n");
        }
        
        // 基于处理速度的建议
        if (stats.getAverageProcessingTimeMs() < 2000) { // 处理很快
            suggestions.append("4. 处理速度良好，可以考虑：\n");
            suggestions.append("   - 适当提高图片DPI以获得更好的识别效果\n");
            suggestions.append("   - 增加图像预处理步骤\n");
            suggestions.append("   - 启用更多语言包\n\n");
        }
        
        if (suggestions.length() == 0) {
            suggestions.append("当前OCR性能表现良好，无需特别优化。");
        }
        
        return suggestions.toString();
    }
    
    /**
     * 重置统计信息
     */
    public void resetStats() {
        totalProcessingTime.set(0);
        totalPagesProcessed.set(0);
        successfulOcrCount.set(0);
        failedOcrCount.set(0);
        peakMemoryUsage.set(0);
        pageProcessingTimes.clear();
    }
    
    /**
     * 获取当前内存使用情况
     */
    public long getCurrentMemoryUsage() {
        Runtime runtime = Runtime.getRuntime();
        return runtime.totalMemory() - runtime.freeMemory();
    }
    
    /**
     * OCR性能统计信息
     */
    public static class OcrPerformanceStats {
        private int totalPagesProcessed;
        private long totalProcessingTimeMs;
        private long averageProcessingTimeMs;
        private int successfulOcrCount;
        private int failedOcrCount;
        private double successRate;
        private long peakMemoryUsageMB;
        
        // Getters and Setters
        public int getTotalPagesProcessed() { return totalPagesProcessed; }
        public void setTotalPagesProcessed(int totalPagesProcessed) { this.totalPagesProcessed = totalPagesProcessed; }
        
        public long getTotalProcessingTimeMs() { return totalProcessingTimeMs; }
        public void setTotalProcessingTimeMs(long totalProcessingTimeMs) { this.totalProcessingTimeMs = totalProcessingTimeMs; }
        
        public long getAverageProcessingTimeMs() { return averageProcessingTimeMs; }
        public void setAverageProcessingTimeMs(long averageProcessingTimeMs) { this.averageProcessingTimeMs = averageProcessingTimeMs; }
        
        public int getSuccessfulOcrCount() { return successfulOcrCount; }
        public void setSuccessfulOcrCount(int successfulOcrCount) { this.successfulOcrCount = successfulOcrCount; }
        
        public int getFailedOcrCount() { return failedOcrCount; }
        public void setFailedOcrCount(int failedOcrCount) { this.failedOcrCount = failedOcrCount; }
        
        public double getSuccessRate() { return successRate; }
        public void setSuccessRate(double successRate) { this.successRate = successRate; }
        
        public long getPeakMemoryUsageMB() { return peakMemoryUsageMB; }
        public void setPeakMemoryUsageMB(long peakMemoryUsageMB) { this.peakMemoryUsageMB = peakMemoryUsageMB; }
        
        @Override
        public String toString() {
            return String.format(
                "OCR性能统计:\n" +
                "- 总处理页数: %d\n" +
                "- 总处理时间: %dms\n" +
                "- 平均处理时间: %dms/页\n" +
                "- 成功识别: %d页\n" +
                "- 识别失败: %d页\n" +
                "- 成功率: %.2f%%\n" +
                "- 峰值内存使用: %dMB",
                totalPagesProcessed, totalProcessingTimeMs, averageProcessingTimeMs,
                successfulOcrCount, failedOcrCount, successRate, peakMemoryUsageMB
            );
        }
    }
} 